<template>
  <textarea id="tinymce" class="tinymce-textarea" v-loading="loading" />
</template>

<script>
const plugins =
  'print preview paste importcss searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount textpattern noneditable help charmap emoticons'
const uploadPlugins =
  'print preview paste importcss searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount imagetools image link media textpattern noneditable help charmap emoticons'
const toolbar =
  'undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent |  numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | fullscreen  preview save print | insertfile template anchor codesample | ltr rtl'
const uploadToolbar =
  'undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent |  numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | fullscreen  preview save print | insertfile image media template link anchor codesample | ltr rtl'
export default {
  props: {
    hasFileUpload: {
      type: Boolean,
      default() {
        return true
      }
    },
    value: {
      type: String,
      default() {
        return ''
      }
    },
    readonly: {
      type: Boolean,
      default() {
        return false
      }
    },
    height: {
      type: Number,
      default() {
        return 200
      }
    },
    getFileUploadToken: {
      type: Function,
      default() {
        return function() {}
      }
    },
    editorUploadFile: {
      type: Function,
      default() {
        return function() {}
      }
    }
  },
  data() {
    return {
      hasChange: false,
      hasInit: false,
      fullscreen: false,
      editorContent: '',
      tinymceId: 'tinymce',
      tokens: {},
      loading: false
    }
  },
  mounted() {
    this.initTinymce()
  },
  activated() {
    this.initTinymce()
  },
  deactivated() {
    this.destroyTinymce()
  },
  destroyed() {
    this.destroyTinymce()
  },
  methods: {
    initTinymce() {
      let _this = this
      window.tinymce.init({
        fontsize_formats: '12px 14px 16px 18px 20px 24px 36px',
        language: 'zh_CN',
        language_url: './static/tinymce/langs/zh_CN.js',
        selector: '#tinymce',
        plugins: this.readonly
          ? ''
          : this.hasFileUpload
          ? uploadPlugins
          : plugins,
        imagetools_cors_hosts: ['picsum.photos'],
        menubar: this.readonly
          ? ''
          : 'file edit view insert format tools table help',
        toolbar: this.readonly
          ? ''
          : this.hasFileUpload
          ? uploadToolbar
          : toolbar,
        readonly: this.readonly,
        toolbar_sticky: true,
        autosave_ask_before_unload: true,
        autosave_interval: '30s',
        autosave_prefix: '{path}{query}-{id}-',
        autosave_restore_when_empty: false,
        autosave_retention: '2m',
        image_advtab: true,
        max_height: 600,
        min_height: 200,
        height: this.height,
        //readonly: this.readonly,
        file_picker_callback: function(callback, value, meta) {
          let tokens = _this.filterTokens(_this.editorContent)
          if (tokens.length >= 8) {
            Tip.warn('附件最大可添加8个，当前已达最大限度')
            return
          }
          //文件分类
          let filetype = ''
          //为不同插件指定文件类型及后端地址
          switch (meta.filetype) {
            case 'image':
              filetype = '.jpg, .jpeg, .png, .gif'
              break
            case 'media':
              filetype = '.mp3, .mp4'
              break
            case 'file':
              filetype = '.jpg, .jpeg, .png, .gif, .mp3, .mp4'
          }
          //模拟出一个input用于添加本地文件
          let input = document.createElement('input')
          input.setAttribute('type', 'file')
          input.setAttribute('accept', filetype)
          input.click()
          input.onchange = async function() {
            Loading.show()
            let file = this.files[0]
            let token = await _this.getFileUploadToken({
              fileName: file.name,
              fileSize: file.size
            })
            let formData = new FormData()
            formData.append('file', file, file.name)
            let res = await _this.editorUploadFile(token, formData)
            if (meta.filetype === 'file') {
              callback(res, { text: file.name })
            }

            // Provide image and alt text for the image dialog
            if (meta.filetype === 'image') {
              callback(res, { alt: file.name })
            }

            // Provide alternative source and posted for the media dialog
            if (meta.filetype === 'media') {
              callback(res, {
                poster: res.replace(/(.*\/)*([^.]+).*/gi, '$2')
              })
            }
            _this.tokens[res.replace(/(.*\/)*([^.]+).*/gi, '$2')] = token
            Loading.hide()
          }
        },
        init_instance_callback: editor => {
          if (this.value) {
            editor.setContent(this.value)
          }
          this.hasInit = true
          editor.on('NodeChange Change SetContent', () => {
            this.hasChange = true
            this.$emit('input', editor.getContent())
            this.filterTokens(editor.getContent())
            this.editorContent = editor.getContent()
          })
          this.changeZindex()
        },
        setup(editor) {
          editor.on('FullscreenStateChanged', e => {
            this.fullscreen = e.state
          })
        }
      })
    },
    changeZindex() {
      let elDialogs = document.querySelectorAll('.el-dialog__wrapper')
      let tinymceToolbar = document.querySelector('.tox-tinymce-aux')
      let maxZindex = 2000
      elDialogs.forEach(e => {
        let index = parseInt(e.style.zIndex)
        if (index > maxZindex) {
          maxZindex = index
        }
      })
      tinymceToolbar.style.zIndex = maxZindex + 1
    },
    destroyTinymce() {
      if (window.tinymce.get(this.tinymceId)) {
        window.tinymce.get(this.tinymceId).destroy()
      }
    },
    // 设置编辑器内容
    setContent(value) {
      window.tinymce.get(this.tinymceId).setContent(value)
    },
    // 获取编辑器内容
    getContent() {
      window.tinymce.get(this.tinymceId).getContent()
    },
    filterTokens(html) {
      let _tokens = []
      for (const key in this.tokens) {
        if (html.includes(key) && !_tokens.find(e => e === this.tokens[key])) {
          _tokens.push(this.tokens[key])
        }
      }
      this.$emit('upload', _tokens)
      return _tokens
    }
  }
}
</script>
